/*******************************************************************************
 * File name: 		startup.S
 * Description: 	init stacks, sections, call main
 * Project:
 * Target: 			LPC1788
 * Compiler: 		arm-none-eabi-gcc
 * Date: 			Jun 15, 2012
 * Author: 			C&C
 * Based on: 		Freddie Chopin, http://www.freddiechopin.info/
 ******************************************************************************/
/*==============================================================================
 Includes
==============================================================================*/
#include "hdr_special_registers.h"

/*==============================================================================
 Global function definitions
==============================================================================*/
/*------------------------------------------------------------------------------
 function name:		Reset_Handler
 description:		reset handler inits stacks, sections and calls main
 parameters:		none
 returned value:	none
------------------------------------------------------------------------------*/

.text
.balign 2
.syntax unified
.thumb
.thumb_func
.global Reset_Handler


Reset_Handler:
/* init process stack pointers */
	ldr		r0, =__process_stack_end
	msr		PSP, r0

	ldr		r0, =__main_stack_end
	msr		MSP, r0

/* Thread mode uses process stack (PSP) and is privileged */
	movs	r0, #CONTROL_ALTERNATE_STACK
	msr		CONTROL, r0
	isb


/* branch to low_level_init_0() function (.data and .bss are not initialized!) */
	ldr		r0, =low_level_init_0
	blx		r0


/* init .data section */
	ldr		r1, =__data_init_start
    ldr		r2, =__data_start
    ldr		r3, =__data_end
1:	cmp		r2, r3
	ittt	lo
	ldrlo	r0, [r1], #4
	strlo	r0, [r2], #4
	blo		1b


/* zero-init .bss section */
	movs	r0, #0
	ldr		r1, =__bss_start
	ldr		r2, =__bss_end
1:	cmp		r1, r2
	itt		lo
	strlo	r0, [r1], #4
	blo		1b


/* call C++ constructors for global and static objects */
#ifdef __USES_CXX
	ldr		r0, =__libc_init_array
	blx		r0
#endif


/* branch to low_level_init_1() function */
	ldr		r0, =low_level_init_1
	blx		r0


/* branch to main() with link */
	ldr		r0, =main
	blx		r0


/* call C++ destructors for global and static objects */
#ifdef __USES_CXX
	ldr		r0, =__libc_fini_array
	blx		r0
#endif


/* on return - loop till the end of the world */
	b		.

/*------------------------------------------------------------------------------
 function name:		__default_low_level_init
 description:		default for low_level_init_0 / 1
 parameters:		none
 returned value:	none
------------------------------------------------------------------------------*/
.text
.balign 2
.syntax unified
.thumb
.thumb_func
.global __default_low_level_init

__default_low_level_init:
	bx		lr


/* assign low_level_init_0 / 1 to __default_low_level_init */
.weak	low_level_init_0
.global	low_level_init_0
.set	low_level_init_0, __default_low_level_init

.weak	low_level_init_1
.global	low_level_init_1
.set	low_level_init_1, __default_low_level_init

/******************************************************************************
* END OF FILE
******************************************************************************/
